package com.guducat.collegeWeb.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.guducat.collegeWeb.dto.request.UserDataSyncDTO;
import com.guducat.collegeWeb.dto.response.UserDataSyncResultDTO;
import com.guducat.collegeWeb.service.UserDataSyncService;
import com.guducat.collegeWeb.dto.request.LoginDTO;
import com.guducat.collegeWeb.dto.response.UserInfoDTO;
import com.guducat.collegeWeb.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;

import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/user")
@Tag(name = "用户管理", description = "提供用户登录、注销、权限验证等功能")
public class UserController {

    private final UserService userService;
    private final UserDataSyncService userDataSyncService;

    @Autowired
    public UserController(UserService userService, UserDataSyncService userDataSyncService) {
        this.userService = userService;
        this.userDataSyncService = userDataSyncService;
    }

    /**
     * 用户登录
     * @param loginDTO 登录信息
     * @return 登录结果
     */
    @Operation(
            summary = "用户登录",
            description = "验证用户名和密码，成功后返回用户信息和token"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "登录成功",
                    content = @Content(mediaType = "application/json",
                            schema = @Schema(implementation = SaResult.class))),
            @ApiResponse(responseCode = "401", description = "用户名或密码错误")
    })
    @PostMapping("/login")
    public SaResult login(
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "登录信息",
                    required = true,
                    content = @Content(schema = @Schema(implementation = LoginDTO.class))
            )
            @RequestBody LoginDTO loginDTO) {
        UserInfoDTO userInfo = userService.login(loginDTO);
        if (userInfo == null) {
            return SaResult.error("用户名或密码错误");
        }
        return SaResult.data(userInfo);
    }

    /**
     * 获取当前登录用户信息
     * @return 用户信息
     */
    @Operation(
            summary = "获取当前登录用户信息",
            description = "获取当前登录用户的详细信息，包括用户名、昵称、头像、权限等",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "成功获取用户信息",
                    content = @Content(mediaType = "application/json",
                            schema = @Schema(implementation = SaResult.class))),
            @ApiResponse(responseCode = "401", description = "未登录或登录已过期")
    })
    @GetMapping("/info")
    @SaCheckLogin
    public SaResult getUserInfo() {
        UserInfoDTO userInfo = userService.getCurrentUserInfo();
        if (userInfo == null) {
            return SaResult.error("获取用户信息失败");
        }
        return SaResult.data(userInfo);
    }

    /**
     * 同步用户个人数据
     * @param syncRequest 用户数据同步请求
     * @return 同步结果
     */
    @Operation(
            summary = "同步用户个人数据",
            description = "同步用户的收藏文章、浏览历史等个人数据。支持上传、下载和合并三种同步模式。",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "同步成功",
                    content = @Content(mediaType = "application/json",
                            schema = @Schema(implementation = SaResult.class))),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未登录或登录已过期"),
            @ApiResponse(responseCode = "403", description = "权限不足")
    })
    @PostMapping("/sync")
    @SaCheckLogin
    public SaResult syncUserData(
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "用户数据同步请求",
                    required = true,
                    content = @Content(schema = @Schema(implementation = UserDataSyncDTO.class))
            )
            @RequestBody @Valid UserDataSyncDTO syncRequest) {

        try {
            // 记录请求信息
            System.out.println("=== 用户数据同步请求 ===");
            System.out.println("请求时间: " + java.time.LocalDateTime.now());
            System.out.println("请求用户ID: " + StpUtil.getLoginIdAsString());
            System.out.println("同步类型: " + syncRequest.getSyncType());
            System.out.println("数据类型: " + syncRequest.getDataTypes());
            System.out.println("客户端版本: " + syncRequest.getClientVersion());
            System.out.println("数据项数量: " + (syncRequest.getDataItems() != null ? syncRequest.getDataItems().size() : 0));
            System.out.println("========================");

            // 调用Service层处理业务逻辑
            UserDataSyncResultDTO result = userDataSyncService.syncUserData(syncRequest);

            if (result.getSuccess()) {
                return SaResult.data(result);
            } else {
                return SaResult.error(result.getErrorMessage());
            }

        } catch (Exception e) {
            System.err.println("同步用户数据时发生异常: " + e.getMessage());
            e.printStackTrace();
            return SaResult.error("系统异常，请稍后重试");
        }
    }

    /**
     * 检查用户是否为管理员
     * @return 是否为管理员
     */
    @GetMapping("/isAdmin")
    @SaCheckLogin
    public SaResult isAdmin() {
        boolean isAdmin = userService.isAdmin();
        return SaResult.data(isAdmin);
    }

    /**
     * 检查用户权限
     * @return 用户权限信息
     */
    @GetMapping("/permission")
    @SaCheckLogin
    public SaResult checkPermission() {
        // 获取用户权限列表
        List<String> permissions = StpUtil.getPermissionList();

        // 检查是否为管理员
        boolean isAdmin = StpUtil.hasPermission("Admin");

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("permissions", permissions);
        result.put("isAdmin", isAdmin);

        return SaResult.data(result);
    }

    /**
     * 检查用户是否有特定权限
     * @param permissionName 权限名称
     * @return 是否有权限
     */
    @GetMapping("/hasPermission")
    @SaCheckLogin
    public SaResult hasPermission(@RequestParam String permissionName) {
        boolean hasPermission = StpUtil.hasPermission(permissionName);
        return SaResult.data(hasPermission);
    }

    /**
     * 用户注销
     * @return 注销结果
     */
    @Operation(
            summary = "用户注销",
            description = "注销当前登录用户，清除登录状态和token"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "注销成功",
                    content = @Content(mediaType = "application/json",
                            schema = @Schema(implementation = SaResult.class)))
    })
    @PostMapping("/logout")
    public SaResult logout() {
        userService.logout();
        return SaResult.ok("注销成功");
    }

    /**
     * 检查登录状态
     * @return 登录状态
     */
    @GetMapping("/isLogin")
    public SaResult isLogin() {
        return SaResult.data(StpUtil.isLogin());
    }

    /**
     * 获取用户数据统计
     * @return 用户数据统计信息
     */
    @Operation(
            summary = "获取用户数据统计",
            description = "获取当前用户的收藏、历史等数据统计信息",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @GetMapping("/data/stats")
    @SaCheckLogin
    public SaResult getUserDataStats() {
        try {
            Integer userId = StpUtil.getLoginIdAsInt();
            var stats = userDataSyncService.getUserDataStats(userId);
            return SaResult.data(stats);
        } catch (Exception e) {
            System.err.println("获取用户数据统计时发生异常: " + e.getMessage());
            e.printStackTrace();
            return SaResult.error("获取统计信息失败");
        }
    }

    /**
     * 清理过期历史记录
     * @param keepDays 保留天数，默认30天
     * @return 清理结果
     */
    @Operation(
            summary = "清理过期历史记录",
            description = "清理指定天数之前的浏览历史记录",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @DeleteMapping("/data/history/cleanup")
    @SaCheckLogin
    public SaResult cleanExpiredHistory(@RequestParam(defaultValue = "30") Integer keepDays) {
        try {
            Integer userId = StpUtil.getLoginIdAsInt();
            int cleanedCount = userDataSyncService.cleanExpiredHistory(userId, keepDays);
            return SaResult.data(Map.of("cleanedCount", cleanedCount, "keepDays", keepDays));
        } catch (Exception e) {
            System.err.println("清理过期历史记录时发生异常: " + e.getMessage());
            e.printStackTrace();
            return SaResult.error("清理历史记录失败");
        }
    }
}
